//using System;  // 引入System命名空间，用于Console等基础类
//实现一个简单的敌人AI决策逻辑，掌握状态机的基本概念。
// 通过模拟敌人AI的巡逻、追击、攻击和逃跑行为，理解游戏AI的设计思路。

/*============== 顶级语句部分（程序入口） ==============*/
// 注意：在C# 9.0+中，顶级语句必须位于所有类型声明之前

// 创建敌人AI实例
var enemyAI = new EnemyAI();
//测试
//Console.WriteLine("初始状态: " + enemyAI.CurrentState);
//修改
// enemyAI.UpdateState();
// Console.WriteLine("修改后状态: " + enemyAI.CurrentState);
//直接修改报错
//enemyAI.CurrentState = EnemyAI.AIState.Attack;


// 打印操作提示
Console.WriteLine("=== 敌人AI决策模拟开始 ===");
Console.WriteLine("按以下键操作：");
Console.WriteLine("1: 玩家接近敌人至5米");
Console.WriteLine("2: 玩家接近敌人至1米");
Console.WriteLine("3: 玩家远离敌人至15米");
Console.WriteLine("4: 攻击敌人（减少20%血量）");
Console.WriteLine("Q: 退出");



// 主循环：持续监听键盘输入
while (true)
{
    // 读取用户输入的字符（不显示按键）
    var input = Console.ReadKey().KeyChar;
    Console.WriteLine();  // 换行

    // 根据输入执行对应操作
    switch (input)
    {
        case '1':
            enemyAI.SetPlayerDistance(5f);  // 设置玩家距离为5米
            break;
        case '2':
            enemyAI.SetPlayerDistance(1f);  // 设置玩家距离为1米
            break;
        case '3':
            enemyAI.SetPlayerDistance(15f); // 重置为初始距离
            break;
        case '4':
            enemyAI.DamageEnemy(20f);       // 对敌人造成20%伤害
            Console.WriteLine(">> 玩家对敌人造成20%伤害！");
            break;
        case 'q':
        case 'Q':
            return;  // 退出程序
    }

    enemyAI.Update(); // 更新AI状态并执行行为
}

/*============== 类型声明部分 ==============*/
/// <summary>
/// 敌人AI控制类，管理状态切换和行为执行
/// </summary>
class EnemyAI
{
    // ========== 状态定义 ==========
    /// <summary>
    /// AI状态枚举
    /// </summary>
    public enum AIState { 
        Patrol,  // 巡逻：默认状态
        Chase,   // 追击：玩家进入中距离范围
        Attack,  // 攻击：玩家进入近战范围
        Flee     // 逃跑：血量低于阈值
    }

    // ========== 属性 ==========
    /// <summary>
    /// 当前AI状态（只读属性）
    /// </summary>
    public AIState CurrentState { get; private set; } = AIState.Patrol;
    //表示该属性只能在类的内部赋值，外部无法修改。
    //（1）封装性
    // 将 CurrentState 的赋值限制在类内部（private set），
    // 可以防止外部代码随意修改状态，确保状态切换的逻辑由类内部控制。
    //这种设计模式在面向对象编程中非常常见，既能保护数据的安全性，又能提供灵活的访问方式

    // ========== 私有字段 ==========
    private float playerDistance;  // 玩家与敌人的距离（单位：米）
    private float enemyHealth;     // 敌人当前血量（百分比，0-100）

    // ========== 构造函数 ==========
    /// <summary>
    /// 初始化敌人参数
    /// </summary>
    public EnemyAI()
    {
        playerDistance = 15f;  // 初始玩家距离15米（安全距离）
        enemyHealth = 100f;    // 初始满血状态
    }

    // ========== 核心方法 ==========
    /// <summary>
    /// 每帧更新方法（模拟游戏循环调用）
    /// 状态执行
    /// </summary>
    public void Update()
    {
        // 阶段1：状态逻辑更新
        UpdateState();

        // 阶段2：执行当前状态行为
        switch (CurrentState)
        {
            case AIState.Patrol:
                Console.WriteLine("[巡逻] 敌人正在路径点A -> B之间移动...");
                break;
            case AIState.Chase:
                Console.WriteLine("[追击] 敌人正在加速接近玩家！");
                break;
            case AIState.Attack:
                Console.WriteLine("[攻击] 敌人挥舞武器，对玩家造成伤害！");
                break;
            case AIState.Flee:
                Console.WriteLine("[逃跑] 敌人血量过低，向反方向逃离！");
                break;
        }

        // 阶段3：输出调试信息
        Console.WriteLine($"当前状态: {CurrentState}, 玩家距离: {playerDistance}米, 血量: {enemyHealth}%");
        Console.WriteLine("----------------------------------");
    }

    // ========== 私有方法 ==========
    /// <summary>
    /// 更新AI状态（状态机逻辑）
    /// 状态切换
    /// 优先级：Flee > Attack > Chase > Patrol
    /// </summary>
    private void UpdateState()
    {
        // 优先检查逃跑条件
        if (enemyHealth <= 20f)
        {
            CurrentState = AIState.Flee;
            return; // 直接返回，跳过后续判断
        }

        // 根据距离判断状态
        if (playerDistance <= 2f)
        {
            CurrentState = AIState.Attack;  // 2米内进入攻击状态
        }
        else if (playerDistance <= 10f)
        {
            CurrentState = AIState.Chase;   // 2-10米进入追击状态
        }
        else
        {
            CurrentState = AIState.Patrol; // 10米外保持巡逻
        }
    }

    // ========== 外部交互方法 ==========
    /// <summary>
    /// 设置玩家距离（模拟玩家位置变化）
    /// </summary>
    /// <param name="distance">新的玩家距离（米）</param>
    public void SetPlayerDistance(float distance) => playerDistance = distance;
    ///表达式主体方法（Expression-bodied Method） 的一种写法，等价于
    ///public void SetPlayerDistance(float distance)
// {
//     playerDistance = distance;
// }
///=> 叫做 lambda 箭头操作符，用于简化只有一行代码的方法或属性。


    /// <summary>
    /// 对敌人造成伤害
    /// </summary>
    /// <param name="damage">伤害值（百分比）</param>
    public void DamageEnemy(float damage) => enemyHealth = Math.Max(0, enemyHealth - damage);
}